/****************************************************
	文件：LevelMgr.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2020/10/12 16:50:9
	功能：关卡管理器
*****************************************************/

using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using HTUtility;
using HTFramework;
using HTFramework.ResKit;
using HTFramework.UIKit;

namespace HTDemo01
{
    public class LevelMgr : Singleton<LevelMgr>
    {
        /// <summary>
        /// 分数
        /// </summary>
        public ReactiveProperty<int> Score;
        /// <summary>
        /// 元素组
        /// </summary>
        public List<int> ItemGroupLst;
        /// <summary>
        /// 各元素生成概率
        /// </summary>
        public List<int> ItemProbabilityLst;
        /// <summary>
        /// 当前关卡数据
        /// </summary>
        public LevelDataItem LevelData;
        /// <summary>
        /// Item元素 GameObject 对象池
        /// </summary>
        public Dictionary<ItemType, GameObjectPool> ItemGoPool;

        /// <summary>
        /// 随机种子
        /// </summary>
        public int RandomSeed;

        /// <summary>
        /// 当前关卡
        /// </summary>
        public int CurLevel { get; private set; }
        /// <summary>
        /// 主摄像机
        /// </summary>
        public Camera MainCamera { get; private set; }

        public void Init(Camera mainCamera)
        {
            MainCamera = mainCamera;
            Score = new ReactiveProperty<int>();
            Score.Subscribe((newScore) =>
            {
                EventCenter.Fire(HTUtility.EventType.LEVEL_SCORE_CHANGE, new object[] { newScore });
            });
            ItemGroupLst = new List<int>();
            ItemProbabilityLst = new List<int>();
            ItemGoPool = new Dictionary<ItemType, GameObjectPool>();
            RandomSeed = 0;

            LevelMap.Instance.Init();

            HTLogger.Info("LevelMgr init done.");
        }

        /// <summary>
        /// 开始关卡
        /// </summary>
        /// <param name="level"></param>
        public void StartLevel(int level)
        {
            CurLevel = level;
            Score.Value = 0;
            SceneMgr.Instance.SubscribeOnLoadSceneEnterCallBack(ReleaseGoPool);
            SceneMgr.Instance.SubscribeOnLoadSceneMidCallBack(PrepareLevel);
            SceneMgr.Instance.SubscribeOnLoadSceneOverCallBack(LevelMap.Instance.BuildMap);
            SceneMgr.Instance.LoadScene(GConsts.LEVEL_SCENE);
            //todo
        }
        /// <summary>
        /// 退出当前关卡
        /// </summary>
        public void ExitLevel()
        {

        }

        /// <summary>
        /// 加载关卡数据
        /// </summary>
        /// <param name="level"></param>
        public void LoadLevelData(int level)
        {
            ItemGroupLst.Clear();
            ItemProbabilityLst.Clear();
            LevelDataScheme scheme = SchemeMgr.Instance.Load<LevelDataScheme>(E_Scheme.LevelData);
            LevelData = scheme.LevelDataList[level - 1];
            if (LevelData == null)
            {
                HTLogger.Error("读取关卡数据失败，关卡ID：{0}", level);
                return;
            }
            foreach (string item in LevelData.ItemGroup.Split(';'))
            {
                ItemGroupLst.Add(Convert.ToInt32(item));
            }
            foreach (string item in LevelData.ItemProbability.Split(';'))
            {
                ItemProbabilityLst.Add(Convert.ToInt32(item));
            }
            if (ItemGroupLst.Count != ItemProbabilityLst.Count)
            {
                HTLogger.Error("关卡 {0} 的元素数据配置错误，ItemGroup 与 ItemProbabilityLst 个数不对等！", level);
            }
        }

        /// <summary>
        /// 准备开始关卡
        /// </summary>
        private void PrepareLevel()
        {
            //加载关卡数据
            HTLogger.Debug("开始加载关卡数据");
            LoadLevelData(CurLevel);

            //加载关卡预制体资源
            PreloadPrefabs();

            //设置主相机位置
            float x = GConsts.ITEM_LENGTH * (LevelData.Width - 1) * 0.5f;
            float y = GConsts.ITEM_LENGTH * (LevelData.Height - 1) * 0.5f;
            MainCamera.transform.position = new Vector3(x, y, -20);

            //加载 Map
            //HTLogger.Debug("开始加载 Map");
            //LevelMap.Instance.BuildMap();
        }
        /// <summary>
        /// 加载关卡预制体资源
        /// </summary>
        private void PreloadPrefabs()
        {
            //ReleaseGoPool();
            //预加载 Item
            string path;
            ItemType itemType;
            foreach (int itemID in ItemGroupLst)
            {
                itemType = (ItemType)itemID;
                path = string.Format("{0}{1}.prefab", GConsts.ITEM_PREFAB_PREFIX_PATH, itemID);
                GameObjectPool pool = new GameObjectPool(path, GOLoader.Instance.RecycleTrans, 100, 50);
                ItemGoPool.Add(itemType, pool);
            }
        }
        /// <summary>
        /// 释放 Item 对象池
        /// </summary>
        private void ReleaseGoPool()
        {
            if (ItemGoPool.Count <= 0) return;
            foreach (var item in ItemGoPool)
            {
                item.Value.RecycleAll(false, false); //销毁资源
            }
            ItemGoPool.Clear();
        }

        /// <summary>
        /// 获取指定 Item 的对象池
        /// </summary>
        /// <param name="itemType"></param>
        /// <returns></returns>
        public GameObjectPool GetItemPool(ItemType itemType)
        {
            GameObjectPool pool = null;
            if (ItemGoPool.TryGetValue(itemType, out pool))
            {
                return pool;
            }
            else
            {
                HTLogger.Error("获取 Item 对象池失败，不存在 {0} 的对象池", itemType);
                return null;
            }
        }
    }
}
